﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http.Json;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace Chaotic.Core.Extension
{
    public static class DataCompression
    {
        public static byte[] ByteCompression(byte[] data, CompressionMode mode)
        {
            GZipStream gZipStream = null;
            try
            {
                if (mode == CompressionMode.Compress)
                {
                    MemoryStream memoryStream = new MemoryStream();
                    using (gZipStream = new GZipStream(memoryStream, mode, leaveOpen: true))
                    {
                        gZipStream.Write(data, 0, data.Length);
                    }

                    return memoryStream.ToArray();
                }

                MemoryStream memoryStream2 = new MemoryStream();
                memoryStream2.Write(data, 0, data.Length);
                memoryStream2.Flush();
                memoryStream2.Position = 0L;
                MemoryStream memoryStream3 = new MemoryStream();
                using (gZipStream = new GZipStream(memoryStream2, mode, leaveOpen: true))
                {
                    byte[] buffer = new byte[1024];
                    int num;
                    do
                    {
                        num = gZipStream.Read(buffer, 0, 1024);
                        if (num == 0)
                        {
                            num = gZipStream.Read(buffer, 0, 1024);
                        }

                        memoryStream3.Write(buffer, 0, num);
                    }
                    while (num != 0);
                }

                return memoryStream3.ToArray();
            }
            catch
            {
                gZipStream?.Close();
                return null;
            }
            finally
            {
                gZipStream?.Close();
            }
        }

        public static byte[] SerializeData<T>(this T data) where T : class
        {
            using MemoryStream memoryStream = new MemoryStream(); 
            JsonSerializer.Serialize(memoryStream, data);
            return memoryStream.ToArray();
        }

        public static T DeserializeData<T>(this byte[] data) where T : class
        {
            if (data != null)
            {
                using (MemoryStream memoryStream = new MemoryStream(data))
                {
                    try
                    {
                        memoryStream.Position = 0L;
                        memoryStream.Seek(0L, SeekOrigin.Begin); 
                        return JsonSerializer.Deserialize<T>(memoryStream);
                    }
                    catch
                    {
                        return null;
                    }
                }
            }

            return null;
        }

        public static void SerializeDataToFile<T>(this T data, string file, JsonConverter jsonContent) where T : class
        {
            using FileStream fileStream = new FileStream(file, FileMode.Create);
            JsonSerializerOptions options = new JsonSerializerOptions
            {
                WriteIndented = true,  //美观打印
                Converters = { jsonContent },
                DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
            };
            JsonSerializer.Serialize(fileStream, data,options);
        }

        public static T DeserializeDataToFile<T>(string file,  JsonConverter jsonContent) where T : class
        {
            if (!File.Exists(file))
            {
                return null;
            }

            JsonSerializerOptions options = new JsonSerializerOptions
            {
                Converters = { jsonContent },
                DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
            };

            using FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read);
            try
            {
                fileStream.Position = 0L;
                fileStream.Seek(0L, SeekOrigin.Begin);
                return JsonSerializer.Deserialize<T>(fileStream, options);
            }
            catch
            {
                return null;
            }
        }
    }
}
